<?php
/**
 * Created by PhpStorm.
 * User: mac
 * Date: 2018/9/13
 * Time: 上午10:37
 */

class User implements SplSubject {
    private $type = '';
    private $observers;

    public function __construct()
    {
        $this->observers = new SplObjectStorage();
    }

    /**
     * 附加观察者
     * @param SplObserver $observer
     */
    public function attach(SplObserver $observer)
    {
        $this->observers->attach($observer);
    }

    /**
     * 取消观察者
     * @param SplObserver $observer
     */
    public function detach(SplObserver $observer)
    {
        $this->observers->detach($observer);
    }

    public function notify()
    {
        //遍历SplObjectStorage就可以拿到所有的观察者
        foreach ($this->observers as $observer) {
            $observer->update($this, $this->type);
        }
    }

    //在给不可访问的属性赋值时，__set()会被调用
    public function __set($name, $value)
    {
        $this->$name = $value;
    }

    //读取不可访问的属性的值时，__get()会被调用。
    public function __get($name)
    {
        return $this->$name;
    }
}

class AUserObserver implements SplObserver {
    public function update(SplSubject $subject)
    {
        switch ($subject->type) {
            case '1':
                echo get_class($subject) . ' login' . PHP_EOL;
                break;
            case '2':
                echo get_class($subject) . ' logout' . PHP_EOL;
                break;
            default:
                echo 'unknown' . PHP_EOL;
                break;
        }
    }
}

class BUserObserver implements SplObserver {
    public function update(SplSubject $subject)
    {
        switch ($subject->type) {
            case '1':
                echo get_class($subject) . ' register' . PHP_EOL;
                break;
            case '2':
                echo get_class($subject) . ' unset' . PHP_EOL;
                break;
            default:
                echo 'unknown' . PHP_EOL;
                break;
        }
    }
}

class CUserObserver implements SplObserver {
    public function update(SplSubject $subject)
    {
        switch ($subject->type) {
            case '1':
                echo get_class($subject) . ' online' . PHP_EOL;
                break;
            case '2':
                echo get_class($subject) . ' offline' . PHP_EOL;
                break;
            default:
                echo 'unknown' . PHP_EOL;
                break;
        }
    }
}

class DUserObserver implements SplObserver {
    public function update(SplSubject $subject)
    {
        switch ($subject->type) {
            case '1':
                echo get_class($subject) . ' left' . PHP_EOL;
                break;
            case '2':
                echo get_class($subject) . ' right' . PHP_EOL;
                break;
            default:
                echo 'unknown' . PHP_EOL;
                break;
        }
    }
}

$a = new AUserObserver();
$b = new BUserObserver();
$c = new CUserObserver();
$d = new DUserObserver();
$user = new User();
$user->attach($a);
$user->attach($b);
$user->attach($c);
$user->attach($d);
$user->type = $argv[1];
$user->notify();